/*********************************************************************************
 *      Copyright:  (C) 2022 Zhang Changxing<ZhangChangxingVIP@163.com>
 *                  All rights reserved.
 *
 *       Filename:  main.c
 *    Description:  This file to achieve SMS sending and view and delete functions.
 *                 
 *        Version:  1.0.0(07/28/2022)
 *         Author:  Zhang Changxing <ZhangChangxingVIP@163.com>
 *      ChangeLog:  1, Release initial version on "07/28/2022  01:33:25 AM"
 *                 
 ********************************************************************************/


#include "main.h"

void install_signal(void);
void handler(int sig);
int identify_sms_type(char *sms_buf);

int g_stop = 0;

int main(int argc, char *argv[])
{
    int     retval = -1;
    char    sms_buf_send[256] = {0};
    int     sms_type = 0;
    int     chose;
    int     ch;
    int     i;
    char    sms_buf_utf8[1024] = {0};
    char    target_number[32] = {0};

    ttyusb_ctx_t ttyusb_ctx;
    ttyusb_ctx_t *ttyusb_ctx_ptr;
    ttyusb_ctx_ptr = &ttyusb_ctx;
    ttyusb_ctx_ptr->timeout = 10;

    log_ctx_t log_ctx;
    log_ctx.loglevel = 2; //LOG_LEVEL_INFO
    strcpy(log_ctx.logfile, "../logger/running.log");
    log_ctx.logsize = 1048576;  //1MB

    struct option opts[] = {
        {"baudrate", required_argument, NULL, 'b'},
        {"databits", required_argument, NULL, 'd'},
        {"parity", required_argument, NULL, 'p'},
        {"stopbits", required_argument, NULL, 's'},
        {"serial_name", required_argument, NULL, 'm'},
        {"help", no_argument, NULL, 'h'},
        {0,0,0,0}
    };
    
    while((ch = getopt_long(argc, argv, "b:d:p:s:m:h", opts, NULL)) != -1)
    {
        switch(ch)
        {
            case 'b':
            {
                ttyusb_ctx_ptr->baudrate = atoi(optarg);
                break;
            }
            case 'd':
            {
                ttyusb_ctx_ptr->databits = atoi(optarg);
                break;
            }
            case 'p':
            {
                ttyusb_ctx_ptr->parity = optarg[0];
                break;
            }
            case 's':
            {
                ttyusb_ctx_ptr->stopbits = atoi(optarg);
                break;
            }
            case 'm':
            {
                strncpy(ttyusb_ctx_ptr->serial_name, optarg, SERIAL_NAME);
                break;
            }
            case 'h':
            {
                print_usage(argv[0]);
                break;
            }
            default:
            {
                printf("%s input invalid argument!\n", __func__);
                return -1;
            }
        }
    }
    
    if(logger_init(log_ctx.logfile, log_ctx.loglevel) < 0)
    {
        fprintf(stderr, "Initial logger system failure\n");
        return -5;
    }

    if(0 == strlen(ttyusb_ctx_ptr->serial_name))
    {
        log_error("Failed to obtain the device name!\n");
        return -1;
    }
    
    install_signal();
    
    if(tty_open(ttyusb_ctx_ptr) < 0)
    {
        log_error("Failed to open the device file");
        return -2;
    }
    
    if(tty_init(ttyusb_ctx_ptr) < 0)
    {
        log_error("Failed to initialize the serial port\n");
        return -3;
    }

    if(check_all_ready(ttyusb_ctx_ptr) < 0)
    {
        log_error("tty or SIM is not ok!\n");
        return -4;
    }
    
    
    while(!g_stop)
    {
        printf("|-----------------------------------------Now you can start-----------------------------------------|\n");
        printf("|                         |                          |                            |                 |\n");
        printf("|  Input <1> Send mesage  |  Input <2> View message  |  Input <3> Delete message  |  Input <4> Quit |\n");
        printf("|                         |                          |                            |                 |\n");
        printf("|---------------------------------------------------------------------------------------------------|\n");
        
        memset(target_number, 0, sizeof(target_number));
        memset(sms_buf_send, 0, sizeof(sms_buf_send));
        printf(">");
        scanf("%d", &chose);
        getchar();
        
        if(1 == chose)
        {
            printf("Enter phone number:\n>");
            scanf("%s", target_number);
            getchar();

            printf("\nEnter SMS:  \n>");
            fgets(sms_buf_send, sizeof(sms_buf_send), stdin);
            for(i = 0; i < sizeof(sms_buf_send); i++)
            {
                if(sms_buf_send[i] == 0x0a)
                {
                    sms_buf_send[i] = 0;
                    break;
                }
            }

            printf("\n");
            sms_type = identify_sms_type(sms_buf_send);
            retval = send_at_cmd(ttyusb_ctx_ptr,"AT+CMEE=2\r","OK",NULL, 0);

            if(1 == sms_type)
            {
                if(send_pdu_sms(ttyusb_ctx_ptr, target_number, sms_buf_send) < 0)
                {
                    printf("Send pdu sms failure!\n");
                    continue;
                }

                printf("Send pdu sms successfully!\n");
                continue;
            }
            else
            {
                log_debug("[%s]sms_buf_send:%s\n", __func__, sms_buf_send);
                if(send_text_sms(ttyusb_ctx_ptr, target_number, sms_buf_send) < 0)
                {
                    
                    printf("Send text sms failure!\n");
                    continue;
                }

                printf("Send text sms successfully!\n");
                continue;
            }
        }        
        else if(2 == chose)
        {
            retval = send_at_cmd(ttyusb_ctx_ptr,"AT+CMGF=0\r","OK",NULL, 0);

            while(!g_stop)
            {
                printf("|---------------------------------Check the SMS--------------------|\n");
                printf("|                             |                                    |\n");
                printf("|  Input <1> View all SMS     |  Input <2> Viewing Specified SMS   |\n");
                printf("|                             |                                    |\n");
                printf("|------------------------------------------------------------------|\n>");
                

                scanf("%d", &chose);
                getchar();

                if(1 == chose)
                {
                    get_all_sms(ttyusb_ctx_ptr, sms_buf_utf8, sizeof(sms_buf_utf8));
                    break;
                }
                else if(2 == chose)
                {
                    printf("Enter target number:\n>");
                    scanf("%s", target_number);
                    getchar();
                    get_specified_sms(ttyusb_ctx_ptr, sms_buf_utf8, sizeof(sms_buf_utf8), target_number);
                    printf("Its latest message is:%s\n", sms_buf_utf8);
                    memset(sms_buf_utf8, 0 , sizeof(sms_buf_utf8));
                    break;
                }
            }
            
        }
        else if(3 == chose)
        {
            retval = send_at_cmd(ttyusb_ctx_ptr,"AT+CMGF=0\r","OK",NULL, 0);

            while(!g_stop)
            {
                printf("Enter phone number:  ");
                scanf("%s", target_number);
                getchar();
                delete_sms(ttyusb_ctx_ptr, target_number);
                break;
            }
        }
        else if(4 == chose){
            goto CleanUp;
        }
    }

    
CleanUp: 
    tty_close(ttyusb_ctx_ptr);
    return retval;
}


int identify_sms_type(char *sms_buf_send)
{
    int rv = 0;
    int i = 0;

    for(i = 0; i < strlen(sms_buf_send); i++)
    {
        if((int)sms_buf_send[i] > 0x7F)
        {
            return 1;
        }
    }

    return 0;
}

void print_usage(char *program_name)
{
    printf("Usage:%s[OPTION]\n\n", program_name);
    printf("-b[baudrate]:Select baud rate, for example 115200 and 9600.\n");
    printf("-p[parity]:Select parity check, for example n N e E o O.\n");
    printf("-s[stopbits]:Select stop bit, for example 1 and 2.\n");
    printf("-m[serial_name]:Select device file, for example /dev/ttyUSB0.\n");
    printf("-h[help]:Printing Help Information.\n"); 
    printf("For example:./SMS -b 115200 -p n -s 1 -m /dev/ttyUSB0 \n\n");

}

void handler(int sig)
{
    switch(sig)
    {
        case SIGINT:
        {
            printf("Process captured SIGINT signal!\n");
            g_stop = 1;
            break;
        }
        case SIGTERM:
        {
            printf("Process captured SIGTERM signal!\n");
            g_stop = 1;
            break;
        }
        case SIGSEGV:
        {
            printf("Process captured SIGSEGV signal!\n");
            g_stop = 1;
            exit(0);
            break;
        }
        case SIGPIPE:
        {
            printf("Process captured SIGPIPE signal!\n");
            g_stop = 1;
            break;
        }
        default:
            break;
    }

    return ;
}

void install_signal(void)
{
    struct sigaction sigact;

    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigact.sa_handler = handler;

    sigaction(SIGINT, &sigact, 0);
    sigaction(SIGTERM, &sigact, 0);
    sigaction(SIGPIPE, &sigact, 0);
    sigaction(SIGSEGV, &sigact, 0);

    return ;
}

